package org.apache.ibatis.executor.statement;

import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.session.ResultHandler;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

/**
 * StatementHandler是MyBatis的核心接口之一
 * 该接口中的功能很多，例如:
 * 1.创建Statement对象
 * 2.为SQL语句绑定实参，
 * 3.执行select、insert、update、delete等多种类型的SQL语句，批量执行SQL语句，
 * 4.将结果集映射成结果对象
 *
 * StatementHandler依赖ParameterHandler和ResultSetHandler完成了MyBatis的核心功能，
 * 它控制着参数绑定、SQL语句执行、结果集映射等一系列核心流程
 *
 * @author Clinton Begin
 */
public interface StatementHandler {

    /**
     * 从连接中获取一个Statement
     *
     * @param connection
     * @param transactionTimeout
     * @return
     * @throws SQLException
     */
    Statement prepare(Connection connection, Integer transactionTimeout)
            throws SQLException;

    /**
     * 绑定statement执行时所需的实参
     *
     * @param statement
     * @throws SQLException
     */
    void parameterize(Statement statement)
            throws SQLException;

    /**
     * 批量执行SQL语句
     *
     * @param statement
     * @throws SQLException
     */
    void batch(Statement statement)
            throws SQLException;

    /**
     * 执行update/insert/delete语句
     *
     * @param statement
     * @return
     * @throws SQLException
     */
    int update(Statement statement)
            throws SQLException;

    /**
     * 执行select语句
     *
     * @param statement
     * @param resultHandler
     * @param <E>
     * @return
     * @throws SQLException
     */
    <E> List<E> query(Statement statement, ResultHandler resultHandler)
            throws SQLException;

    /**
     * 执行带游标的select语句
     * 当查询百万级的数据的时候，使用游标可以节省内存的消耗，
     * 不需要一次性取出所有数据，可以进行逐条处理或逐条取出部分批量处理。
     *
     * @param statement
     * @param <E>
     * @return
     * @throws SQLException
     */
    <E> Cursor<E> queryCursor(Statement statement)
            throws SQLException;

    /**
     * 获取boundSql
     *
     * @return
     */
    BoundSql getBoundSql();

    /**
     * 获取其中封装的ParameterHandler
     *
     * @return
     */
    ParameterHandler getParameterHandler();

}
